package com.group01.Interceptors;

import com.group01.enums.CodeAndMessageEnum;
import com.group01.exception.SystemException;
import com.group01.utils.JwtUtil;
import com.group01.utils.LogUtil;
import com.group01.utils.ThreadLocalUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.MalformedJwtException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Description 登录拦截器
 * @Author 翟玉龙
 * @Date 2024/6/20
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    private final StringRedisTemplate redisTemplate;

    public LoginInterceptor(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if(request.getMethod().equals("OPTIONS")) {
            return true;
        }
        // 获取token
        String token = request.getHeader("Authorization");
        // 验证token
        try {
            // 获取redis中的token
            ValueOperations<String , String> operations = redisTemplate.opsForValue();

            // 解析token
            Map<String , Object> claims = JwtUtil.parseToken(token);

            /*
             * 解析后的键值对 -> ids 和 username
             */

            // 打印token信息 (键值对)
            for (String key : claims.keySet()) {
                System.out.println(key + " ：" + claims.get(key));
            }
            String redisToken = operations.get("token" + claims.get("id") + "," + claims.get("roleId")); // 获取不同用户的Token缓存值

            // 不存在token或者已经失效
            if(redisToken == null || !redisToken.equals(token)) {
                throw new JwtException("token不存在或者已经失效");
            }

            // 判断用户权限
            if(!claims.get("roleId").toString().equals("1")) {
                throw new SystemException(CodeAndMessageEnum.NO_PERMISSION);
            }

            // 把业务数据存储到ThreadLocal中
            ThreadLocalUtil.set(claims);

            // 放行
            return true;
        } catch (ExpiredJwtException e) {
            LogUtil.error("token过期: " , e);
            throw new SystemException(CodeAndMessageEnum.TOKEN_EXPIRED);
        } catch (MalformedJwtException e) {
            LogUtil.error("token格式错误: " , e);
            throw new SystemException(CodeAndMessageEnum.TOKEN_MALFORMED);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 运行后移除ThreadLocal，防止内存溢出
        ThreadLocalUtil.remove();
    }

}
